package handler

import (
	"apibe/single/src/v1/factory"
	"apibe/single/src/v1/factory/shortcut"
	"apibe/single/src/v1/service"
	"apibe/single/src/v1/service/impl"
	"apibe/single/src/v1/share/crypt"
	"context"
	"encoding/json"
	"errors"
	"go.mongodb.org/mongo-driver/bson"
	"net/http"
	"time"
)

/*
	DesignHandler
	接口转换核心逻辑处理
*/
func DesignHandler(catch map[string]string, apiName string, claims *crypt.CustomClaims) ([]byte, int, bool, error) {
	start := time.Now().UnixNano()
	design, err := factory.GetDesign(apiName)
	if err != nil {
		return nil, http.StatusOK, false, errors.New("can not find this api design")
	}
	body, status, cache, err := design.AutoAssembly(catch, 30*time.Second) // 执行
	duration := time.Now().UnixNano() - start
	{
		// 存储用户行为
		description, _ := json.Marshal(catch)
		if status == http.StatusOK && duration < 12*1000000000 {
			factory.ActionLogger(factory.Info, apiName, claims, string(description))
		} else {
			factory.ActionLogger(factory.Err, apiName, claims, string(description))
		}
		shortcut.ApiWatch(status, apiName, duration) // api 接口监测
	}
	if err != nil {
		return nil, status, cache, err
	}
	return body, status, cache, nil
}

/*
	创建|修改
	根据传入的 _id 进行区分，当 _id 为nil时，创建
	当 _id 不为空时，修改
*/
func DesignUpsertHandler(design *impl.Design, claims *crypt.CustomClaims) error {
	taskService, _ := service.NewService(service.TaskService)
	designService, _ := service.NewService(service.DesignService)
	taskExist := taskService.Exist(bson.M{"api_name": design.ApiName, "status": bson.M{"$ne": factory.Deleted}})
	designExist := designService.Exist(bson.M{"api_name": design.ApiName})
	if taskExist && designExist {
		return errors.New("design has task and have not delete")
	}
	_, err := design.UpsertOne(claims)
	return err
}

/*
	根据条件获取所有的 design (包含logger)
*/
func DesignFindManyHandler(filter map[string]interface{}, page int, pageSize int) (*[]impl.Design, int64, error) {
	design, err := service.NewService(service.DesignService)
	taskService, err := service.NewService(service.TaskService)
	if err != nil {
		return nil, 0, err
	}
	cursor, count, err := design.FindManyFilter(filter, page, pageSize)
	if err != nil {
		return nil, 0, err
	}
	var ds []impl.Design
	err = cursor.All(context.Background(), &ds)
	for i, d := range ds {
		ds[i].Task = taskService.Exist(bson.M{"api_name": d.ApiName, "status": bson.M{"$lt": factory.Deleted}}) // 每个api_name最多只能创建10个任务
	}
	if err != nil {
		return nil, 0, err
	}
	return &ds, count, err
}
